package com.zg.indiv.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.common.core.dao.indiv.IndivDataTypeDao;
import com.zg.common.core.dao.indiv.IndivFolderDao;
import com.zg.common.core.dao.indiv.entity.IndivDataType;
import com.zg.common.core.dao.indiv.entity.IndivFolder;
import com.zg.common.core.exception.BusinessException;
import com.zg.indiv.constants.IndivConstant;
import com.zg.indiv.constants.IndivExceptionEnum;
import com.zg.indiv.domain.req.dataType.*;
import com.zg.indiv.service.IndivDataTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author lixin
 */
@Service
@RequiredArgsConstructor
public class IndivDataTypeServiceImpl implements IndivDataTypeService {
    private final IndivDataTypeDao indivDataTypeDao;
    private final IndivFolderDao indivFolderDao;

    @Override
    public IPage<IndivDataType> page(IndivDataTypePageReq param) {
        LambdaQueryWrapper<IndivDataType> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String searchStr = param.getSearchStr();
        lambdaQueryWrapper.like(StrUtil.isNotBlank(searchStr), IndivDataType::getSearchStr, "%" + searchStr + "%");
        lambdaQueryWrapper.eq(param.getSpaceId() != null, IndivDataType::getSpaceId, param.getSpaceId());
        lambdaQueryWrapper.eq(param.getFolderId() != null, IndivDataType::getFolderId, param.getFolderId());
        lambdaQueryWrapper.eq(param.getType() != null, IndivDataType::getType, param.getType());
        lambdaQueryWrapper.orderByAsc(IndivDataType::getUpdateTime);
        return indivDataTypeDao.page(
                new Page<>(param.getPage(), param.getPageSize()),
                lambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(IndivDataTypeAddReq param) {
        IndivFolder indivFolder = indivFolderDao.getById(param.getFolderId());
        if (indivFolder == null) {
            BusinessException.happen(IndivExceptionEnum.FOLDER_NO.getCode(),
                    IndivExceptionEnum.FOLDER_NO.getMsg());
        }

        long nameCount = indivDataTypeDao.count(
                new LambdaQueryWrapper<IndivDataType>()
                        .eq(IndivDataType::getFolderId, param.getFolderId())
                        .eq(IndivDataType::getName, param.getName())
        );
        if (nameCount > 0) {
            BusinessException.happen(IndivExceptionEnum.DATA_TYPE_NAME_ERROR.getCode(),
                    IndivExceptionEnum.DATA_TYPE_NAME_ERROR.getMsg());
        }

        if (IndivConstant.INDIV_DATA_TYPE_FORM.equals(param.getType())) {
            if (param.getFormId() == null) {
                BusinessException.happen(IndivExceptionEnum.DATA_TYPE_FORM_NO.getCode(),
                        IndivExceptionEnum.DATA_TYPE_FORM_NO.getMsg());
            }
            param.setFileType(null);
        } else if (IndivConstant.INDIV_DATA_TYPE_FILE.equals(param.getType())){
            if (StrUtil.isBlank(param.getFileType())) {
                BusinessException.happen(IndivExceptionEnum.DATA_TYPE_FILE_NO.getCode(),
                        IndivExceptionEnum.DATA_TYPE_FILE_NO.getMsg());
            }
            param.setFormId(null);
        } else {
            BusinessException.happen(IndivExceptionEnum.DATA_TYPE_TYPE_NO.getCode(),
                    IndivExceptionEnum.DATA_TYPE_TYPE_NO.getMsg());
        }

        IndivDataType indivDataType = new IndivDataType();
        BeanUtil.copyProperties(param, indivDataType);
        indivDataType.setSpaceId(indivFolder.getSpaceId());
        indivDataType.setSearchStr(param.getName());
        indivDataTypeDao.save(indivDataType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(IndivDataTypeEditReq param) {
        IndivDataType indivDataType = indivDataTypeDao.getById(param.getDataTypeId());
        if (indivDataType == null) {
            BusinessException.happen(IndivExceptionEnum.DATA_TYPE_NO.getCode(),
                    IndivExceptionEnum.DATA_TYPE_NO.getMsg());
        }

        if (!indivDataType.getName().equals(param.getName())) {
            long nameCount = indivDataTypeDao.count(
                    new LambdaQueryWrapper<IndivDataType>()
                            .eq(IndivDataType::getFolderId, indivDataType.getFolderId())
                            .eq(IndivDataType::getName, param.getName())
            );
            if (nameCount > 0) {
                BusinessException.happen(IndivExceptionEnum.DATA_TYPE_NAME_ERROR.getCode(),
                        IndivExceptionEnum.DATA_TYPE_NAME_ERROR.getMsg());
            }
        }

        if (IndivConstant.INDIV_DATA_TYPE_FORM.equals(param.getType())) {
            if (param.getFormId() == null) {
                BusinessException.happen(IndivExceptionEnum.DATA_TYPE_FORM_NO.getCode(),
                        IndivExceptionEnum.DATA_TYPE_FORM_NO.getMsg());
            }
            param.setFileType(null);
        } else if (IndivConstant.INDIV_DATA_TYPE_FILE.equals(param.getType())){
            if (StrUtil.isBlank(param.getFileType())) {
                BusinessException.happen(IndivExceptionEnum.DATA_TYPE_FILE_NO.getCode(),
                        IndivExceptionEnum.DATA_TYPE_FILE_NO.getMsg());
            }
            param.setFormId(null);
        } else {
            BusinessException.happen(IndivExceptionEnum.DATA_TYPE_TYPE_NO.getCode(),
                    IndivExceptionEnum.DATA_TYPE_TYPE_NO.getMsg());
        }

        BeanUtil.copyProperties(param, indivDataType);
        indivDataType.setSearchStr(indivDataType.getName());
        indivDataTypeDao.updateById(indivDataType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(List<Long> idList) {
        indivDataTypeDao.removeBatchByIds(idList);
    }

}
